﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Threading;
using CSharp.Libs.Koc;
using System.Collections.ObjectModel;
using CSharp.Libs.Koc.ItemClasses;
using CSharp.Libs.Koc.KernelModels;
using System.Collections;

namespace CSharp.Libs.WPF.UserControls
{
    public class KocKnightSelectorViewModel : ViewModelBase
    {
        #region declarations
        private Dispatcher _DISP = null;
        private Kernel _KRNL = null;

        private ObservableCollection<KnightItem> _ocKnightList = new ObservableCollection<KnightItem>();

        private KnightItem _selectedKnight = null;

        private KnightItem _kiNoServerUser = null;    //shows up in Knightbox when no User or Server is selected in KernelControl
        private KnightItem _kiNoSeed = null;          //shows up in Knightbox when the selected User - Server combo didn't receive a seed yet
        private KnightItem _kiNoCity = null;          //shows up in Knightbox when the selected User - Server combo didn't receive a seed yet

        private string _strUserFbUid = "";
        private int _intServerNr = 0;
        private int _intSelectedCityId = 0;

        private const string NO_SERVER_USER = "<No server/user selected>";
        private const string NO_SEED = "<No seed yet>";
        private const string NO_CITY_SELECTED = "<No city selected>";

        #region events
        public delegate void KnightSelectedEventHandler(object sender, SelectedKnightEventArgs skea);
        public event KnightSelectedEventHandler KnightSelected;
        private void ThrowKnightSelectedEvent(
            SelectedKnightEventArgs skea)
        {
            if (KnightSelected != null)
            {
                KnightSelected(this, skea);
            }
        }
        #endregion
        #endregion



        #region constructor / finalizer
        public KocKnightSelectorViewModel(
            Dispatcher DISP,
            Kernel KRNL)
        {
            _DISP = DISP;
            _KRNL = KRNL;

            _KRNL.SC.SeedReceived += new SeedCollector.SeedReceivedEventHandler(SC_SeedReceived);

            _initTempKnights();
        }
        #endregion



        #region event handling
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="srea"></param>
        /// <history>created  04.07.2012</history>
        void SC_SeedReceived(object sender, SeedReceivedEventArgs srea)
        {
            //build knight list
            _createKnightList();//HIER doch nicht... tztz // KLAR hier. Wenn User und Server schon ausgewählt sind und der nur noch auf den Seed wartet???? Mann mann....
        }
        #endregion



        #region private functions
        /// <summary>
        /// 
        /// </summary>
        /// <history>created  04.07.2012</history>
        private void _initTempKnights()
        {
            _kiNoServerUser = new KnightItem();
            _kiNoServerUser.KnightName = NO_SERVER_USER;

            _kiNoSeed = new KnightItem();
            _kiNoSeed.KnightName = NO_SEED;

            _kiNoCity = new KnightItem();
            _kiNoCity.KnightName = NO_CITY_SELECTED;

            _AddKnight(_kiNoServerUser);
            SelectedKnight = _kiNoServerUser;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <history>created  04.07.2012</history>
        private void _createKnightList()
        {
            //clear citylist
            _clearKnights();

            //switch to select first city
            bool fFirstKnight = true;

            //check if user and server are selected
            if (UserFbUid != "" &&
               ServerNr > 0)
            {
                //check if seed was received
                string strKey = _KRNL.SC.GetKey(UserFbUid, ServerNr.ToString());
                if (_KRNL.SC.Seeds.ContainsKey(strKey))
                {
                    //build city list
                    SeedHolder SH = new SeedHolder(_KRNL, _KRNL.SC.Seeds[strKey] as Hashtable);

                    //Break out if selected City is not existing.
                    if (!SH.CityKnights.ContainsKey("city" + _intSelectedCityId.ToString()))
                    {
                        _AddKnight(_kiNoCity);
                        return;
                    }
                    
                    //get knights of City
                    CityKnightsItem CKI = SH.CityKnights["city" + _intSelectedCityId.ToString()];
                    
                    foreach (KeyValuePair<string, KnightItem> KVP in CKI.Knights)
                    {
                        KnightItem kiCurrent = KVP.Value;

                        _AddKnight(kiCurrent);

                        //select first city automatically
                        if (fFirstKnight)
                        {
                            setSelectedKnight(kiCurrent);
                            fFirstKnight = false;
                        }
                    }
                }
                else
                {
                    _AddKnight(_kiNoSeed);
                    SelectedKnight = _kiNoSeed;
                }
            }
            else
            {
                _AddKnight(_kiNoServerUser);
                SelectedKnight = _kiNoServerUser;
            }
        }

        #region UI-invokes
        /// <summary></summary>
        /// <history>created  04.07.2012</history>
        private void _clearKnights()
        {
            _DISP.Invoke((Action)delegate
            {
                _ocKnightList.Clear();
                SelectedKnight = null;
                OnPropertyChanged("Knights");
                OnPropertyChanged("SelectedKnight");
            });
        }

        /// <summary></summary>
        /// <param name="CI"></param>
        /// <history>created  04.07.2012</history>
        private void _AddKnight(
            KnightItem KI)
        {
            _DISP.Invoke((Action)delegate
            {
                _ocKnightList.Add(KI);
                OnPropertyChanged("Knights");
            });
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="ciSelect"></param>
        /// <history>created  04.07.2012</history>
        private void setSelectedKnight(
            KnightItem kiSelect)
        {
            _DISP.Invoke((Action)delegate
            {
                SelectedKnight = kiSelect;
                OnPropertyChanged("SelectedKnight");
            });
        }
        #endregion
        #endregion



        #region interface
        #region properties
        /// <summary>
        /// 
        /// </summary>
        /// <history>created  05.07.2012</history>
        public int SelectedCityId
        {
            get { return _intSelectedCityId; }
            set
            {
                _intSelectedCityId = value;
                _createKnightList();
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <history>created  04.07.2012</history>
        public ObservableCollection<KnightItem> Knights { get { return _ocKnightList; } }

        /// <summary>
        /// 
        /// </summary>
        /// <history>created  04.07.2012</history>
        public KnightItem SelectedKnight
        {
            get { return _selectedKnight; }
            set
            {
                _selectedKnight = value;
                if (_selectedKnight != null)
                {
                    OnPropertyChanged("SelectedKnight");

                    if (_selectedKnight != _kiNoServerUser && 
                        _selectedKnight != _kiNoSeed)
                    {
                        ThrowKnightSelectedEvent(new SelectedKnightEventArgs(_selectedKnight));
                    }
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <history>created  09.07.2012</history>
        public int ServerNr { get { return _intServerNr; } set { _intServerNr = value; _createKnightList(); } }

        /// <summary>
        /// 
        /// </summary>
        /// <history>created  09.07.2012</history>
        public string UserFbUid { get { return _strUserFbUid; } set { _strUserFbUid = value; _createKnightList(); } }
        #endregion

        #region methods
        #endregion
        #endregion
    }
}
